package com.shangguosha.factory;

import com.shangguosha.model.Character;
import com.shangguosha.model.characters.TestCharacter;
import com.shangguosha.model.enums.Gender;
import com.shangguosha.model.enums.Kingdom;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * 角色工厂类
 * 负责创建和管理游戏中的所有角色
 */
@Slf4j
public class CharacterFactory {
    
    private static final Map<String, CharacterInfo> CHARACTER_REGISTRY = new HashMap<>();
    private static final Random random = new Random();
    
    static {
        // 注册所有可用角色
        registerCharacters();
    }
    
    /**
     * 角色信息类
     */
    private static class CharacterInfo {
        private final String name;
        private final Kingdom kingdom;
        private final Gender gender;
        private final int maxHp;
        private final Class<? extends Character> characterClass;
        
        public CharacterInfo(String name, Kingdom kingdom, Gender gender, int maxHp, Class<? extends Character> characterClass) {
            this.name = name;
            this.kingdom = kingdom;
            this.gender = gender;
            this.maxHp = maxHp;
            this.characterClass = characterClass;
        }
    }
    
    /**
     * 注册所有角色
     */
    private static void registerCharacters() {
        // 蜀国角色
        registerCharacter("liubei", "刘备", Kingdom.SHU, Gender.MALE, 4, TestCharacter.class);
        registerCharacter("guanyu", "关羽", Kingdom.SHU, Gender.MALE, 4, TestCharacter.class);
        registerCharacter("zhangfei", "张飞", Kingdom.SHU, Gender.MALE, 4, TestCharacter.class);
        registerCharacter("zhaoyun", "赵云", Kingdom.SHU, Gender.MALE, 4, TestCharacter.class);
        registerCharacter("machao", "马超", Kingdom.SHU, Gender.MALE, 4, TestCharacter.class);
        registerCharacter("huangzhong", "黄忠", Kingdom.SHU, Gender.MALE, 4, TestCharacter.class);
        registerCharacter("zhugeliang", "诸葛亮", Kingdom.SHU, Gender.MALE, 3, TestCharacter.class);
        
        // 魏国角色
        registerCharacter("caocao", "曹操", Kingdom.WEI, Gender.MALE, 4, TestCharacter.class);
        registerCharacter("simayi", "司马懿", Kingdom.WEI, Gender.MALE, 3, TestCharacter.class);
        registerCharacter("xiahoudun", "夏侯惇", Kingdom.WEI, Gender.MALE, 4, TestCharacter.class);
        registerCharacter("zhangliao", "张辽", Kingdom.WEI, Gender.MALE, 4, TestCharacter.class);
        registerCharacter("xuchu", "许褚", Kingdom.WEI, Gender.MALE, 4, TestCharacter.class);
        registerCharacter("guojia", "郭嘉", Kingdom.WEI, Gender.MALE, 3, TestCharacter.class);
        registerCharacter("zhenji", "甄姬", Kingdom.WEI, Gender.FEMALE, 3, TestCharacter.class);
        
        // 吴国角色
        registerCharacter("sunquan", "孙权", Kingdom.WU, Gender.MALE, 4, TestCharacter.class);
        registerCharacter("ganning", "甘宁", Kingdom.WU, Gender.MALE, 4, TestCharacter.class);
        registerCharacter("lvmeng", "吕蒙", Kingdom.WU, Gender.MALE, 4, TestCharacter.class);
        registerCharacter("huanggai", "黄盖", Kingdom.WU, Gender.MALE, 4, TestCharacter.class);
        registerCharacter("zhouyu", "周瑜", Kingdom.WU, Gender.MALE, 3, TestCharacter.class);
        registerCharacter("daqiao", "大乔", Kingdom.WU, Gender.FEMALE, 3, TestCharacter.class);
        registerCharacter("xiaoqiao", "小乔", Kingdom.WU, Gender.FEMALE, 3, TestCharacter.class);
        
        // 群雄角色
        registerCharacter("dongzhuo", "董卓", Kingdom.QUN, Gender.MALE, 4, TestCharacter.class);
        registerCharacter("lvbu", "吕布", Kingdom.QUN, Gender.MALE, 4, TestCharacter.class);
        registerCharacter("diaochan", "貂蝉", Kingdom.QUN, Gender.FEMALE, 3, TestCharacter.class);
        registerCharacter("huatuo", "华佗", Kingdom.QUN, Gender.MALE, 3, TestCharacter.class);
        registerCharacter("yuanshao", "袁绍", Kingdom.QUN, Gender.MALE, 4, TestCharacter.class);
        registerCharacter("yanliangwenchou", "颜良文丑", Kingdom.QUN, Gender.MALE, 4, TestCharacter.class);
        
        log.info("已注册 {} 个角色", CHARACTER_REGISTRY.size());
    }
    
    /**
     * 注册角色
     */
    private static void registerCharacter(String id, String name, Kingdom kingdom, Gender gender, int maxHp, Class<? extends Character> characterClass) {
        CHARACTER_REGISTRY.put(id, new CharacterInfo(name, kingdom, gender, maxHp, characterClass));
    }
    
    /**
     * 根据ID创建角色
     */
    public static Character createCharacter(String characterId, String playerId) {
        CharacterInfo info = CHARACTER_REGISTRY.get(characterId);
        if (info == null) {
            log.warn("未找到角色: {}", characterId);
            return null;
        }
        
        try {
            // 使用反射创建角色实例
            return info.characterClass.getDeclaredConstructor(String.class, String.class, Kingdom.class, Gender.class, int.class)
                    .newInstance(playerId, info.name, info.kingdom, info.gender, info.maxHp);
        } catch (Exception e) {
            log.error("创建角色失败: {}", characterId, e);
            return new TestCharacter(playerId, info.name, info.kingdom, info.gender, info.maxHp);
        }
    }
    
    /**
     * 创建随机角色
     */
    public static Character createRandomCharacter(String playerId) {
        List<String> characterIds = new ArrayList<>(CHARACTER_REGISTRY.keySet());
        String randomId = characterIds.get(random.nextInt(characterIds.size()));
        return createCharacter(randomId, playerId);
    }
    
    /**
     * 根据势力创建随机角色
     */
    public static Character createRandomCharacterByKingdom(String playerId, Kingdom kingdom) {
        List<String> matchingIds = CHARACTER_REGISTRY.entrySet().stream()
                .filter(entry -> entry.getValue().kingdom == kingdom)
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());
        
        if (matchingIds.isEmpty()) {
            log.warn("没有找到势力为 {} 的角色", kingdom);
            return createRandomCharacter(playerId);
        }
        
        String randomId = matchingIds.get(random.nextInt(matchingIds.size()));
        return createCharacter(randomId, playerId);
    }
    
    /**
     * 获取所有可用角色ID
     */
    public static List<String> getAllCharacterIds() {
        return new ArrayList<>(CHARACTER_REGISTRY.keySet());
    }
    
    /**
     * 获取指定势力的所有角色ID
     */
    public static List<String> getCharacterIdsByKingdom(Kingdom kingdom) {
        return CHARACTER_REGISTRY.entrySet().stream()
                .filter(entry -> entry.getValue().kingdom == kingdom)
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());
    }
    
    /**
     * 获取角色信息
     */
    public static String getCharacterInfo(String characterId) {
        CharacterInfo info = CHARACTER_REGISTRY.get(characterId);
        if (info == null) {
            return "未知角色";
        }
        
        return String.format("%s [%s] (%s, %d体力)", 
                info.name, info.kingdom, info.gender, info.maxHp);
    }
    
    /**
     * 检查角色是否存在
     */
    public static boolean hasCharacter(String characterId) {
        return CHARACTER_REGISTRY.containsKey(characterId);
    }
    
    /**
     * 创建测试用角色列表
     */
    public static List<Character> createTestCharacters(int playerCount) {
        List<Character> characters = new ArrayList<>();
        List<String> characterIds = getAllCharacterIds();
        
        for (int i = 0; i < playerCount && i < characterIds.size(); i++) {
            String playerId = "player" + (i + 1);
            String characterId = characterIds.get(i);
            Character character = createCharacter(characterId, playerId);
            if (character != null) {
                characters.add(character);
            }
        }
        
        return characters;
    }
    
    /**
     * 创建平衡的角色列表（每个势力尽量平均）
     */
    public static List<Character> createBalancedCharacters(int playerCount) {
        List<Character> characters = new ArrayList<>();
        Kingdom[] kingdoms = Kingdom.values();
        
        for (int i = 0; i < playerCount; i++) {
            String playerId = "player" + (i + 1);
            Kingdom kingdom = kingdoms[i % kingdoms.length];
            Character character = createRandomCharacterByKingdom(playerId, kingdom);
            if (character != null) {
                characters.add(character);
            }
        }
        
        return characters;
    }
}